package com.we.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import static java.math.BigDecimal.ROUND_HALF_UP;
import static java.util.Calendar.*;
import static java.util.Calendar.DATE;

public class CommonTimeTools {
    public static Logger LOG = LoggerFactory.getLogger(CommonTimeTools.class);

    public static long millSecondsOfDay = 24 * 3600 * 1000;

    public static int getHourOfTime(long time) {
        Calendar instance = Calendar.getInstance();
        instance.setTimeInMillis(time);
        return instance.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * sunday = 1 saturday = 7
     *
     * @param time
     * @return
     */
    public static int getDayOfWeek(long time) {
        Calendar instance = Calendar.getInstance();
        instance.setTimeInMillis(time);
        return instance.get(DAY_OF_WEEK);
    }

    //    public static String getHourPart(long time) {
    //        int part = getHourOfTime(time);
    //        if(part >= 1 && part <= 6){
    //            return H1_6;
    //        } else if(part >= 7 && part <= 12){
    //            return H7_12;
    //        } else if(part >= 13 && part <= 18) {
    //            return H13_18;
    //        } else if((part >= 19 && part <= 23) || part == 0){
    //            return H19_24;
    //        } else {
    //            LOG.error("getHourPart wrong param: " + time);
    //            return null;
    //        }
    //    }

    public static long timeBeforeDays(long now, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(now);
        calendar.add(Calendar.DATE, -days);
        long res = calendar.getTimeInMillis();
        return res;
    }

    public static long getStartTimeOfDay(long now, SimpleDateFormat sdf) throws Exception {
        String date = sdf.format(new Date(now));
        long res = 0;
        try {
            res = sdf.parse(date).getTime();
        } catch (Exception e) {
            throw new Exception("cant not parse time: " + now);
        }
        return res;
    }

    public static Integer dateDiff(Long time1, Long time2, SimpleDateFormat sdf) throws Exception {
        if (time1 == null || time2 == null) {
            return null;
        }
        long startTimeOfDay = getStartTimeOfDay(time1, sdf);
        long startTimeOfDay1 = getStartTimeOfDay(time2, sdf);

        int diff = (int) ((startTimeOfDay - startTimeOfDay1) / millSecondsOfDay);
        return diff;
    }

    public static Integer dateDiffBetAuditRegTime(Long time1, Long time2, SimpleDateFormat sdf)
            throws Exception {
        if (time1 == null || time2 == null) {
            return null;
        }
        long startTimeOfDay = getStartTimeOfDay(time1 * 1000, sdf);
        long startTimeOfDay1 = getStartTimeOfDay(time2 * 1000, sdf);

        int diff = (int) ((startTimeOfDay - startTimeOfDay1) / millSecondsOfDay);
        return diff;
    }

    public static Integer getYearOfTime(long time) {
        Calendar instance = getInstance();
        instance.setTimeInMillis(time);
        return instance.get(YEAR);
    }

    public static Integer monthDiff(Long time1, Long time2) {
        if (time1 == null || time2 == null) {
            return null;
        }
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();

        cal1.setTimeInMillis(time1);
        cal2.setTimeInMillis(time2);

        int monDiffInt =
                (cal1.get(YEAR) - cal2.get(YEAR)) * 12 + (cal1.get(MONTH) - cal2.get(MONTH));

        if (cal1.get(DATE) == cal2.get(DATE)
                || (cal1.get(DATE) == cal1.getActualMaximum(DATE)
                        && cal2.get(DATE) == cal2.getActualMaximum(DATE))) {
            return monDiffInt;
        }

        int sec1 = getDayPartInSec(cal1);
        int sec2 = getDayPartInSec(cal2);

        // 1 sec is 0.000000373 months (1/2678400). 1 month is 31 days.
        // there should be no adjustments for leap seconds
        double monBtwDbl = monDiffInt + (sec1 - sec2) / 2678400D;
        // Round a double to 8 decimal places.
        double result = BigDecimal.valueOf(monBtwDbl).setScale(8, ROUND_HALF_UP).doubleValue();
        return (int) Math.ceil(result);
    }

    private static int getDayPartInSec(Calendar cal) {
        int dd = cal.get(DATE);
        int HH = cal.get(HOUR_OF_DAY);
        int mm = cal.get(MINUTE);
        int ss = cal.get(SECOND);
        int dayInSec = dd * 86400 + HH * 3600 + mm * 60 + ss;
        return dayInSec;
    }

    public static void main(String[] args) {
        //        System.out.println("monthDiff: " + monthDiff(1667104551734L, 1634187291000L));
        System.out.println(getYearOfTime(315417600000L));
    }
}
